package cn.rocksolid.sport.security.service.impl;

import cn.rocksolid.sport.common.error.RSE;
import cn.rocksolid.sport.common.error.RockSolidException;
import cn.rocksolid.sport.security.dao.CaptchaDao;
import cn.rocksolid.sport.security.entity.CaptchaEntity;
import cn.rocksolid.sport.security.service.CaptchaService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
 * System captcha service implementation
 *
 * @author Axl Zhao
 * @email axl.zhao@163.com
 */
@Service
public class CaptchaServiceImpl extends ServiceImpl<CaptchaDao, CaptchaEntity> implements CaptchaService {

  private static final int SEC_5_MINUTES = 5 * 60;

  @Override
  @Transactional(rollbackFor = Exception.class)
  public void create(final String uuid, final String code) {
    create(uuid, code, SEC_5_MINUTES);
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public void create(final String uuid, final String code, final int seconds) {
    if (StringUtils.isBlank(uuid) || StringUtils.isBlank(code)) {
      throw new RockSolidException(RSE.INVALID_PAYLOAD);
    }
    CaptchaEntity captchaEntity = new CaptchaEntity();
    captchaEntity.setUuid(uuid);
    captchaEntity.setCode(code);
    captchaEntity.setExpireTime(DateUtils.addSeconds(new Date(), seconds));
    this.save(captchaEntity);
  }

  @Override
  @Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_COMMITTED)
  public boolean verify(final String uuid, final String code) {
    CaptchaEntity captchaEntity = this.getById(uuid);
    this.removeById(uuid);
    if (null == captchaEntity) {
      throw new RockSolidException(RSE.CAPTCHA_MISMATCH);
    }
    if (!captchaEntity.getCode().equalsIgnoreCase(code)) {
      throw new RockSolidException(RSE.CAPTCHA_MISMATCH);
    }
    if (captchaEntity.getExpireTime().getTime() < System.currentTimeMillis()) {
      throw new RockSolidException(RSE.CAPTCHA_EXPIRED);
    }
    return true;
  }
}
